﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace ValidationFramework.Tests
{
	[TestFixture]
	public class ParameterKeyTest
	{
		#region Test Model

		public void TestMethod()
		{
			// for testing
		}
		public void TestMethod2()
		{
			// for testing
		}

		#endregion

		[Test]
		public void Hash_Code_Should_Match_For_Same_Keys()
		{
			var key1 = new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod");
			var key2 = new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod");

			Assert.AreEqual(key1.GetHashCode(), key2.GetHashCode());
		}
		[Test]
		public void Hash_Code_Should_Be_Different_For_Different_Keys()
		{
			var key1 = new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod");
			var key2 = new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod2");

			Assert.AreNotEqual(key1.GetHashCode(), key2.GetHashCode());

			var key3 = new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod");
			var key4 = new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod2").MethodHandle), "TestMethod");

			Assert.AreNotEqual(key3.GetHashCode(), key4.GetHashCode());
		}
		[Test]
		public void Should_Be_Able_To_Add_Two_Different_Keys_To_Generic_Dictionary()
		{
			var dictionary = new Dictionary<ParameterKey, string>();

			dictionary.Add(new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod"), "Value");
			dictionary.Add(new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod2").MethodHandle), "TestMethod"), "Value");

			Assert.AreEqual(2, dictionary.Count);

			var dictionary2 = new Dictionary<ParameterKey, string>();

			dictionary2.Add(new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod"), "Value");
			dictionary2.Add(new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod2"), "Value2");

			Assert.AreEqual(2, dictionary.Count);
		}
		[Test]
		[ExpectedException(typeof(ArgumentException))]
		public void Should_Not_Be_Able_To_Add_Two_Identical_Keys_To_Generic_Dictionary()
		{
			var dictionary = new Dictionary<ParameterKey, string>();

			dictionary.Add(new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod"), "Value");
			dictionary.Add(new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod"), "Value");

			Assert.AreEqual(1, dictionary.Count);
		}
		[Test]
		public void Should_Return_Correct_Value_From_Generic_Dictionary()
		{
			var dictionary = new Dictionary<ParameterKey, string>();
			var key = new ParameterKey(new MethodKey(typeof(ParameterKeyTest).GetMethod("TestMethod").MethodHandle), "TestMethod");

			dictionary.Add(key, "Value");

			// by tryGetValue
			string value;
			dictionary.TryGetValue(key, out value);
			Assert.AreEqual("Value", value);

			// by index
			Assert.AreEqual("Value", dictionary[key]);
		}
	}
}
